<template>
  <el-card shadow="hover" class="mt-20">
    <el-form
      label-width="auto"
      ref="spuFormRef"
      :model="spuFormData"
      :rules="supFormRules">
      <el-form-item label="SPU名称" prop="spuName">
        <el-input placeholder="请输入SPU名称" v-model="spuFormData.spuName" />
      </el-form-item>

      <el-form-item label="品牌" prop="tmId">
        <el-select placeholder="请选择品牌" v-model="spuFormData.tmId">
          <el-option
            v-for="tm in trademarkList"
            :key="tm.id"
            :value="tm.id"
            :label="tm.tmName" />
        </el-select>
      </el-form-item>

      <el-form-item label="请输入SPU描述" prop="description">
        <el-input
          type="textarea"
          placeholder="SPU描述"
          :rows="3"
          v-model="spuFormData.description" />
      </el-form-item>

      <el-form-item label="SPU图片" prop="spuImageList">
        <el-upload
          v-model:file-list="spuFormData.spuImageList"
          :action="`${BASE_URL}/admin/product/upload`"
          list-type="picture-card"
          :on-preview="handlePictureCardPreview"
          :before-upload="beforeAvatarUpload"
          :on-success="handleUpdateSuccess">
          <el-icon>
            <Plus />
          </el-icon>

          <template #tip>
            <div class="el-upload__tip">只能上传jpg/png文件，且不超过200kb</div>
          </template>
        </el-upload>

        <el-dialog v-model="dialogVisible" width="50%">
          <img w-full :src="dialogImageUrl" alt="预览图片" class="spu_img" />
        </el-dialog>
      </el-form-item>

      <el-form-item label="销售属性" prop="spuSaleAttrList">
        <el-select
          :placeholder="baseSaleAttrPlaceholder"
          style="margin-right: 10px"
          v-model="selectedBaseSaleAttr">
          <el-option
            v-for="baseSale in filteredBaseSaleAttrList"
            :key="baseSale.id"
            :value="`${baseSale.id} : ${baseSale.name}`"
            :label="baseSale.name" />
        </el-select>
        <el-button
          type="primary"
          :icon="CirclePlusFilled"
          @click="addSaleAttr"
          :disabled="!selectedBaseSaleAttr">
          添加销售属性
        </el-button>

        <el-table :data="spuFormData.spuSaleAttrList" border class="mt-20">
          <el-table-column
            label="序号"
            width="80"
            align="center"
            type="index" />
          <el-table-column prop="saleAttrName" label="属性名" width="150" />
          <el-table-column label="属性值名称列表">
            <template v-slot="{ row }">
              <el-tag
                type="success"
                class="mr-10"
                closable
                v-for="(spuSaleAttrValue, index) in row.spuSaleAttrValueList"
                :key="spuSaleAttrValue.saleAttrValueName"
                @close="delSpuAttr(row.spuSaleAttrValueList, index)">
                {{ spuSaleAttrValue.saleAttrValueName }}
              </el-tag>
              <el-input
                v-if="row.isShowEdit"
                size="small"
                class="spu__input--w-100"
                v-model.trim="saleAttrValueName"
                ref="inputRef"
                @blur="switchShow(row)"
                @keyup.enter="switchShow(row)"></el-input>
              <el-button
                v-else
                :icon="Plus"
                size="small"
                @click="switchEdit(row)"></el-button>
            </template>
          </el-table-column>
          <el-table-column prop="xxx" label="操作" width="130">
            <template v-slot="{ row, $index }">
              <el-popconfirm
                :title="`确定要删除${row.saleAttrName}吗?`"
                @confirm="delSpuSaleAttr($index)">
                <template #reference>
                  <el-button
                    type="danger"
                    :icon="Delete"
                    size="small"></el-button
                ></template>
              </el-popconfirm>
            </template>
          </el-table-column>
        </el-table>
      </el-form-item>

      <el-form-item class="mt-20" label=" ">
        <el-button type="primary" @click="submit">保存</el-button>
        <el-button @click="isShowSupList">取消</el-button>
      </el-form-item>
    </el-form>
  </el-card>
</template>

<script lang="ts">
export default {
  name: "AddOrUpdateSpu",
};
</script>

<script lang="ts" setup>
import { ref, reactive, computed, onMounted, nextTick } from "vue";
import { CirclePlusFilled, Delete, Plus } from "@element-plus/icons-vue";
import { ElMessage } from "element-plus";
import { getAllTradeMarkListApi } from "@/api/product/trademark";
import {
  getSpuSaleAttrListApi,
  addSpuListAPi,
  updateSpuApi,
  getSpuImageListApi,
  getSpuAttrListApi,
} from "@/api/product/spu";
import { useCategoryStore } from "@/stores/category";
import { useSpuStore } from "@/stores/spu";
import type { TrademarkList } from "@/api/product/model/trademarkModel";
import type {
  BaseSaleAttrList,
  SpuFormData,
  SpuSaleAttrItem,
  SpuSaleAttrValueList,
  SpuSaleAttrList,
} from "@/api/product/model/spuModel";
import type { UploadProps } from "element-plus";
const categoryStore = useCategoryStore();
const spuStore = useSpuStore();

// 获取品牌、销售属性
const trademarkList = ref<TrademarkList>([]); // 获取品牌
const baseSaleAttrList = ref<BaseSaleAttrList>([]); // 获取销售属性
onMounted(async () => {
  trademarkList.value = await getAllTradeMarkListApi();
});
onMounted(async () => {
  baseSaleAttrList.value = await getSpuSaleAttrListApi();
});

// 获取图片展示
onMounted(async () => {
  const id = spuStore.spu.id as number;
  // 点击的是添加就没id  修改就携带id
  if (!id) return;
  const spuImageList = await getSpuImageListApi(id);
  // 映射 请求回来的数据 和 展示的数据名不一样 要处理一下
  spuFormData.spuImageList = spuImageList.map((img) => {
    return {
      name: img.imgName,
      url: img.imgUrl,
      // 这里是方便添加新图片 可以得到图片地址
      response: {
        data: img.imgUrl,
      },
    };
  });
});

// 获取属性展示
onMounted(async () => {
  const id = spuStore.spu.id as number;
  if (!id) return;
  spuFormData.spuSaleAttrList = await getSpuAttrListApi(id);
});

// // 销售属性功能
const filteredBaseSaleAttrList = computed(() => {
  return baseSaleAttrList.value.filter((baseSaleAttr) => {
    if (
      spuFormData.spuSaleAttrList.some(
        (spuSaleAttr) => baseSaleAttr.id === spuSaleAttr.baseSaleAttrId
      )
    ) {
      return false;
    }
    return true;
  });
});
// 计算还有多少个未选择
const baseSaleAttrPlaceholder = computed(() => {
  // return filteredBaseSaleAttrList.value.length;
  const length = filteredBaseSaleAttrList.value.length;
  return length ? `还剩${length}个销售属性` : "没有啦";
});

// 收集销售属性id 和 name
const selectedBaseSaleAttr = ref("");
// 添加销售属性列表
const addSaleAttr = () => {
  const [id, name] = selectedBaseSaleAttr.value.split(":");
  spuFormData.spuSaleAttrList.push({
    baseSaleAttrId: +id,
    saleAttrName: name,
    spuSaleAttrValueList: [],
    isShowEdit: false,
  });
  selectedBaseSaleAttr.value = "";
};
// 删除销售属性列表
const delSpuSaleAttr = (index: number) => {
  spuFormData.spuSaleAttrList.splice(index, 1);
};

// 用来获取input焦点
const inputRef = ref();

// 编辑收集的数据
const saleAttrValueName = ref("");

// 显示或编辑
const switchEdit = async (row: SpuSaleAttrItem) => {
  row.isShowEdit = true;
  await nextTick();
  inputRef.value.focus();
};
// 添加tag属性
const switchShow = (row: SpuSaleAttrItem) => {
  row.isShowEdit = false;

  if (
    row.spuSaleAttrValueList.some(
      (item) => item.saleAttrValueName === saleAttrValueName.value
    )
  ) {
    ElMessage.warning("不能输入不同值");
    return;
  }

  if (!saleAttrValueName.value) return;
  row.spuSaleAttrValueList.push({
    baseSaleAttrId: row.baseSaleAttrId,
    saleAttrValueName: saleAttrValueName.value,
  });
  saleAttrValueName.value = "";
};

// 删除tag属性

const delSpuAttr = (
  spuSaleAttrValueList: SpuSaleAttrValueList,
  index: number
) => {
  spuSaleAttrValueList.splice(index, 1);
};
// 上传图片路径
const BASE_URL = import.meta.env.VITE_API_URL;

const dialogImageUrl = ref("");
const dialogVisible = ref(false);

// 图片预览勾子
const handlePictureCardPreview: UploadProps["onPreview"] = (uploadFile) => {
  dialogImageUrl.value = uploadFile.url as string;
  dialogVisible.value = true;
};

// 上传文件之前的钩子
const beforeAvatarUpload: UploadProps["beforeUpload"] = (rawFile) => {
  const fileTypes = ["image/jpeg", "image/png", "image/gif"];
  // 不是上述的图片类型就提示错误
  if (!fileTypes.includes(rawFile.type)) {
    ElMessage.error("上传图片只能是jpg或png格式!");
    // 返回false 上传失败 不会上传
    return false;
  } else if (rawFile.size / 1024 > 3000) {
    ElMessage.error("图片大小不能超过200kb!");
    return false;
  }
  return true;
};

// 获取表单实例
const spuFormRef = ref();
// 定义数据
const spuFormData = reactive<SpuFormData>({
  spuName: spuStore.spu.spuName,
  tmId: spuStore.spu.tmId,
  description: spuStore.spu.description,
  spuImageList: [],
  spuSaleAttrList: [],
});

const spuSaleAttrListValidator = (
  rule: any,
  value: SpuSaleAttrList,
  callback: any
) => {
  // 判断是否选择三个销售属性
  if (!value.length) {
    callback(new Error("请至少添加一个销售属性"));
    return;
  }
  // 判断是否输入 tag属性列表
  if (value.some((spuSaleAttr) => !spuSaleAttr.spuSaleAttrValueList.length)) {
    callback(new Error(" 每个销售属性请至少添加一个销售属性值"));
    return;
  }
  // 必填 效验通过
  callback();
};

// 定义表单验证规则
const supFormRules = reactive({
  spuName: [{ required: true, message: "请输入SPU名称", trigger: "blur" }],
  tmId: [{ required: true, message: "请输入SPU品牌", trigger: "change" }],
  description: [{ required: true, message: "请输入SPU描述", trigger: "blur" }],
  spuImageList: [{ required: true, message: "请输入SPU图片", trigger: "blur" }],
  spuSaleAttrList: [
    {
      required: true,
      // 简单的效验规则，不能判断数组中的数据是否有值，所以用自定义规则
      validator: spuSaleAttrListValidator,
    },
  ],
});

// 点击保存对整个表单进行验证
const submit = async () => {
  // 对整个表单进行验证
  await spuFormRef.value.validate();

  const id = spuStore.spu.id;

  const data = {
    category3Id: categoryStore.category3Id,
    ...spuFormData,
    spuImageList: spuFormData.spuImageList.map((img) => {
      return {
        imgName: img.name,
        imgUrl: (img.response as { data: string }).data,
      };
    }),
  };
  // 有id 就是修改
  if (id) {
    await updateSpuApi({
      ...data,
      id,
    });
  } else {
    await addSpuListAPi(data);
  }

  ElMessage.success(`${id ? "修改" : "添加"}Spu成功`);
  isShowSupList();
};

// 图片上传触发的勾子 清除验证表单的提示
const handleUpdateSuccess = () => {
  spuFormRef.value.clearValidate(["spuImageList"]);
};

// 控制添加图片最大的数量
const MAX_UPLOAD_LIMIT = 10;

// 切换组件
const isShowSupList = () => {
  emit("setIsShow", 1);
};

// 定义图片到达一定数量 隐藏添加的元素
const isUploadHidden = computed(() => {
  return spuFormData.spuImageList.length < MAX_UPLOAD_LIMIT
    ? "inline-flex"
    : "none";
});
// 自定义函数
const emit = defineEmits(["setIsShow"]);
</script>

<style scoped>
.spu_img {
  width: 100%;
}
:deep(.el-upload) {
  display: v-bind(isUploadHidden);
}

.spu__input--w-100 {
  width: 100px;
}
</style>
